﻿using Newtonsoft.Json;
using RestSharp;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using Yz.Base;
using Yz.Core.Tools;

namespace Yz.Core.Apis
{

    public class RestSharpApi
    {
        #region Get方法
        /// <summary>
        /// get请求，返回response
        /// </summary>
        /// <param name="apiUrl">接口地址（ip+端口）</param>
        /// <param name="apiFunUrl">方法地址</param>
        /// <returns></returns>
        public static IRestResponse GetResponse(string apiUrl, string apiFunUrl, List<KeyValuePair<string, string>> headers = null)
        {
            var strbUrl = new StringBuilder();
            strbUrl.Append(apiFunUrl);
            var request = new RestRequest(strbUrl.ToString(), Method.GET);
            if (headers != null && headers.Count > 0)
            {
                request.AddHeaders(headers);
            }
            var restClient = new RestClient(apiUrl);
            return restClient.Execute(request);
        }
        /// <summary>
        /// get请求，返回response
        /// </summary>
        /// <param name="apiUrl">接口地址（ip+端口）</param>
        /// <param name="apiFunUrl">方法地址</param>
        /// <returns></returns>
        public static async Task<IRestResponse> GetResponseAsync(string apiUrl, string apiFunUrl, List<KeyValuePair<string, string>> headers = null)
        {
            var strbUrl = new StringBuilder();
            strbUrl.Append(apiFunUrl);
            var request = new RestRequest(strbUrl.ToString(), Method.GET);
            if (headers != null && headers.Count > 0)
            {
                request.AddHeaders(headers);
            }
            var restClient = new RestClient(apiUrl);
            return await restClient.ExecuteAsync(request);
        }
        /// <summary>
        ///     调用接口返回字符串
        /// </summary>
        /// <param name="apiUrl">接口地址（ip+端口）</param>
        /// <param name="apiFunUrl">方法地址</param>
        /// <param name="func">解密方法，为空，不解密</param>
        /// <returns></returns>
        public static string GetContent(string apiUrl, string apiFunUrl, List<KeyValuePair<string, string>> headers = null, Func<string, string> func = null)
        {
            var resp = GetResponse(apiUrl, apiFunUrl, headers);
            if (resp.ErrorException != null)
            {
                YzNLog.Error(resp.ErrorException);
            }
            string content = resp.Content;
            if (func != null)
            {
                content = func.DynamicInvoke(content).ToString();
            }
            else
            {
                content = content.Replace("\\", "").Trim('"');
            }
            return content;
        }
        /// <summary>
        ///     调用接口返回字符串
        /// </summary>
        /// <param name="apiUrl">接口地址（ip+端口）</param>
        /// <param name="apiFunUrl">方法地址</param>
        /// <param name="func">解密方法，为空，不解密</param>
        /// <returns></returns>
        public static async Task<string> GetContentAsync(string apiUrl, string apiFunUrl, List<KeyValuePair<string, string>> headers = null, Func<string, string> func = null)
        {
            var resp = await GetResponseAsync(apiUrl, apiFunUrl, headers);
            if (resp.ErrorException != null)
            {
                YzNLog.Error(resp.ErrorException);
            }
            string content = resp.Content;
            if (func != null)
            {
                content = func.DynamicInvoke(content).ToString();
            }
            else
            {
                content = content.Replace("\\", "").Trim('"');
            }
            return content;
        }
        /// <summary>
        ///     调用接口转换成强类型（单个model）
        /// </summary>
        /// <param name="apiUrl">接口地址（ip+端口）</param>
        /// <param name="apiFunUrl">方法地址</param>
        /// <param name="func">解密方法，为空不解密</param>
        /// <returns></returns>
        public static T GetData<T>(string apiUrl, string apiFunUrl, List<KeyValuePair<string, string>> headers = null, Func<string, string> func = null) where T : ApiModel
        {
            var resp = GetResponse(apiUrl, apiFunUrl, headers);
            if (resp.ErrorException != null)
            {
                YzNLog.Error(resp.ErrorException);
            }
            string content = resp.Content;
            if (func != null)
            {
                content = func.DynamicInvoke(content).ToString();
            }
            return JsonConvert.DeserializeObject<T>(content);
        }
        /// <summary>
        ///     调用接口转换成强类型（单个model）
        /// </summary>
        /// <param name="apiUrl">接口地址（ip+端口）</param>
        /// <param name="apiFunUrl">方法地址</param>
        /// <param name="func">解密方法，为空不解密</param>
        /// <returns></returns>
        public static async Task<T> GetDataAsync<T>(string apiUrl, string apiFunUrl, List<KeyValuePair<string, string>> headers = null, Func<string, string> func = null) where T : ApiModel
        {
            var resp = await GetResponseAsync(apiUrl, apiFunUrl, headers);
            if (resp.ErrorException != null)
            {
                YzNLog.Error(resp.ErrorException);
            }
            string content = resp.Content;
            if (func != null)
            {
                content = func.DynamicInvoke(content).ToString();
            }
            return JsonConvert.DeserializeObject<T>(content);
        }

        #endregion

        #region Post方法
        /// <summary>
        ///     调用接口转换成强类型（List<model>）
        /// </summary>
        /// <param name="apiUrl">接口地址（ip+端口）</param>
        /// <param name="apiFunUrl">方法地址</param>
        /// <param name="paras">参数</param>
        /// <param name="isJson">参数是否是xml</param> 
        /// <returns></returns>
        public static IRestResponse PostResponse(string apiUrl, string apiFunUrl, object paras = null, List<KeyValuePair<string, string>> headers = null, bool isXml = false)
        {
            var strbUrl = new StringBuilder();
            strbUrl.Append(apiFunUrl);
            var request = new RestRequest(strbUrl.ToString(), Method.POST);
            if (headers != null && headers.Count > 0)
            {
                request.AddHeaders(headers);
            }
            if (paras != null)
            {
                if (isXml)
                {
                    request.AddXmlBody(paras);

                }
                else
                {
                    request.AddJsonBody(paras);
                }
            }
            var restClient = new RestClient(apiUrl);
            return restClient.Execute(request);
        }
        /// <summary>
        ///     调用接口转换成强类型（List<model>）
        /// </summary>
        /// <param name="apiUrl">接口地址（ip+端口）</param>
        /// <param name="apiFunUrl">方法地址</param>
        /// <param name="paras">参数</param>
        /// <param name="isJson">参数是否是xml</param> 
        /// <returns></returns>
        public static async Task<IRestResponse> PostResponseAsync(string apiUrl, string apiFunUrl, object paras = null, List<KeyValuePair<string, string>> headers = null, bool isXml = false)
        {
            var strbUrl = new StringBuilder();
            strbUrl.Append(apiFunUrl);
            var request = new RestRequest(strbUrl.ToString(), Method.POST);
            if (headers != null && headers.Count > 0)
            {
                request.AddHeaders(headers);
            }
            if (paras != null)
            {
                if (isXml)
                {
                    request.AddXmlBody(paras);

                }
                else
                {
                    request.AddJsonBody(paras);
                }
            }
            var restClient = new RestClient(apiUrl);
            return await restClient.ExecuteAsync(request);
        }
        /// <summary>
        ///     调用接口返回字符串
        /// </summary>
        /// <param name="apiUrl">接口地址（ip+端口）</param>
        /// <param name="apiFunUrl">方法地址</param>
        /// <param name="paras">参数</param>
        /// <param name="isJson">参数是否是xml</param> 
        /// <param name="func">解密方法，为空不解密</param>
        /// <returns></returns>
        public static string PostContent(string apiUrl, string apiFunUrl, object paras = null, List<KeyValuePair<string, string>> headers = null, bool isXml = false, Func<string, string> func = null)
        {
            var resp = PostResponse(apiUrl, apiFunUrl, paras, headers, isXml);
            if (resp.ErrorException != null)
            {
                YzNLog.Error(resp.ErrorException);
            }
            string content = resp.Content;
            if (func != null)
            {
                content = func.DynamicInvoke(content).ToString();
            }
            else
            {
                content = content.Replace("\\", "").Trim('"');
            }
            return content;
        }
        /// <summary>
        ///     调用接口返回字符串
        /// </summary>
        /// <param name="apiUrl">接口地址（ip+端口）</param>
        /// <param name="apiFunUrl">方法地址</param>
        /// <param name="paras">参数</param>
        /// <param name="isJson">参数是否是xml</param> 
        /// <param name="func">解密方法，为空不解密</param>
        /// <returns></returns>
        public static async Task<string> PostContentAsync(string apiUrl, string apiFunUrl, object paras = null, List<KeyValuePair<string, string>> headers = null, bool isXml = false, Func<string, string> func = null)
        {
            var resp = await PostResponseAsync(apiUrl, apiFunUrl, paras, headers, isXml);
            if (resp.ErrorException != null)
            {
                YzNLog.Error(resp.ErrorException);
            }
            string content = resp.Content;
            if (func != null)
            {
                content = func.DynamicInvoke(content).ToString();
            }
            else
            {
                content = content.Replace("\\", "").Trim('"');
            }
            return content;
        }
        /// <summary>
        ///     调用接口转换成强类型（List<model>）
        /// </summary>
        /// <param name="apiUrl">接口地址（ip+端口）</param>
        /// <param name="apiFunUrl">方法地址</param>
        /// <param name="paras">参数</param>
        /// <param name="isJson">参数是否是xml</param> 
        /// <param name="func">解密方法，为空不解密</param>
        /// <returns></returns>
        public static T PostData<T>(string apiUrl, string apiFunUrl, object paras = null, List<KeyValuePair<string, string>> headers = null, bool isXml = false, Func<string, string> func = null) where T : ApiModel
        {
            var resp = PostResponse(apiUrl, apiFunUrl, paras, headers, isXml);
            if (resp.ErrorException != null)
            {
                YzNLog.Error(resp.ErrorException);
            }
            string content = resp.Content;
            if (func != null)
            {
                content = func.DynamicInvoke(content).ToString();
            }
            return JsonConvert.DeserializeObject<T>(content);
        }
        /// <summary>
        ///     调用接口转换成强类型（List<model>）
        /// </summary>
        /// <param name="apiUrl">接口地址（ip+端口）</param>
        /// <param name="apiFunUrl">方法地址</param>
        /// <param name="paras">参数</param>
        /// <param name="isJson">参数是否是xml</param> 
        /// <param name="func">解密方法，为空不解密</param>
        /// <returns></returns>
        public static async Task<T> PostDataAsync<T>(string apiUrl, string apiFunUrl, object paras = null, List<KeyValuePair<string, string>> headers = null, bool isXml = false, Func<string, string> func = null) where T : ApiModel
        {
            var resp = await PostResponseAsync(apiUrl, apiFunUrl, paras, headers, isXml);
            if (resp.ErrorException != null)
            {
                YzNLog.Error(resp.ErrorException);
            }
            string content = resp.Content;
            if (func != null)
            {
                content = func.DynamicInvoke(content).ToString();
            }
            return JsonConvert.DeserializeObject<T>(content);
        }
        /// <summary>
        /// 上传文件
        /// </summary>
        /// <param name="apiUrl">接口地址（ip+端口）</param>
        /// <param name="apiFunUrl">方法地址</param>
        /// <param name="file">文件信息</param>
        /// <param name="paras">参数</param>
        /// <param name="isJson">参数是否是xml</param>
        /// <returns></returns>
        public static IRestResponse PostFile(string apiUrl, string apiFunUrl, ApiFile file, object paras = null, List<KeyValuePair<string, string>> headers = null, bool isXml = false)
        {
            var strbUrl = new StringBuilder();
            strbUrl.Append(apiFunUrl);
            var request = new RestRequest(strbUrl.ToString(), Method.POST);
            if (headers != null && headers.Count > 0)
            {
                request.AddHeaders(headers);
            }
            if (paras != null)
            {
                if (isXml)
                {
                    request.AddXmlBody(paras);
                }
                else
                {
                    request.AddJsonBody(paras);
                }
            }
            request.AddFile(file.Name, file.FileBytes, file.FileName, file.ContentType);
            var restClient = new RestClient(apiUrl);
            return restClient.Execute(request);
        }
        /// <summary>
        /// 上传文件
        /// </summary>
        /// <param name="apiUrl">接口地址（ip+端口）</param>
        /// <param name="apiFunUrl">方法地址</param>
        /// <param name="file">文件信息</param>
        /// <param name="paras">参数</param>
        /// <param name="isJson">参数是否是xml</param>
        /// <returns></returns>
        public static async Task<IRestResponse> PostFileAsync(string apiUrl, string apiFunUrl, ApiFile file, object paras = null, List<KeyValuePair<string, string>> headers = null, bool isXml = false)
        {
            var strbUrl = new StringBuilder();
            strbUrl.Append(apiFunUrl);
            var request = new RestRequest(strbUrl.ToString(), Method.POST);
            if (headers != null && headers.Count > 0)
            {
                request.AddHeaders(headers);
            }
            if (paras != null)
            {
                if (isXml)
                {
                    request.AddXmlBody(paras);
                }
                else
                {
                    request.AddJsonBody(paras);
                }
            }
            request.AddFile(file.Name, file.FileBytes, file.FileName, file.ContentType);
            var restClient = new RestClient(apiUrl);
            return await restClient.ExecuteAsync(request);
        }
        #endregion

        /// <summary>
        /// 现在远程文件
        /// </summary>
        /// <param name="apiUrl"></param>
        /// <param name="apiFunUrl"></param>
        /// <param name="paras"></param>
        /// <param name="headers"></param>
        /// <param name="isXml"></param>
        /// <param name="method"></param>
        /// <returns></returns>
        public static async Task<BaseApiFile> DownLoadFileAsync(string apiUrl, string apiFunUrl, object paras = null, Dictionary<string, string> headers = null, bool isXml = false, Method method = Method.GET)
        {
            var strbUrl = new StringBuilder();
            strbUrl.Append(apiFunUrl);
            var request = new RestRequest(strbUrl.ToString(), method);
            if (headers != null)
            {
                foreach (var item in headers)
                {
                    request.AddHeader(item.Key, item.Value);
                }
            }
            if (paras != null)
            {
                if (isXml)
                {
                    request.AddXmlBody(paras);
                }
                else
                {
                    request.AddJsonBody(paras);
                }
            }
            var restClient = new RestClient(apiUrl);
            IRestResponse response = await restClient.ExecuteAsync(request, method);
            var bytes = response.RawBytes;
            return new BaseApiFile()
            {
                FileBytes = bytes,
                ContentType = response.ContentType
            };
        }

        /// <summary>
        /// 现在远程文件
        /// </summary>
        /// <param name="apiUrl"></param>
        /// <param name="apiFunUrl"></param>
        /// <param name="paras"></param>
        /// <param name="headers"></param>
        /// <param name="isXml"></param>
        /// <param name="method"></param>
        /// <returns></returns>
        public static BaseApiFile DownLoadFile(string apiUrl, string apiFunUrl, object paras = null, Dictionary<string, string> headers = null, bool isXml = false, Method method = Method.GET)
        {
            var strbUrl = new StringBuilder();
            strbUrl.Append(apiFunUrl);
            var request = new RestRequest(strbUrl.ToString(), method);
            if (headers != null)
            {
                foreach (var item in headers)
                {
                    request.AddHeader(item.Key, item.Value);
                }
            }
            if (paras != null)
            {
                if (isXml)
                {
                    request.AddXmlBody(paras);
                }
                else
                {
                    request.AddJsonBody(paras);
                }
            }
            var restClient = new RestClient(apiUrl);
            IRestResponse response = restClient.Execute(request, method);
            var bytes = response.RawBytes;
            return new BaseApiFile()
            {
                FileBytes = bytes,
                ContentType = response.ContentType
            };
        }
    }


}
